/*

This program will numerically compute the integral of

                  4/(1+x*x) 
				  
from 0 to 1.  The value of this integral is pi -- which 
is great since it gives us an easy way to check the answer.

The is the original sequential program.  It uses the timer
from the OpenMP runtime library

History: Written by Tim Mattson, 11/99.

*/
#include <stdio.h>
#include <omp.h>
static long num_steps = 1000000000;
double step;

double interval_sum_up(const double step, const int num_worker){
	const int my_rank=omp_get_thread_num();
	const int local_num_step=(num_steps%num_worker)==0?num_steps/num_worker:num_steps/num_worker+1;
	const int left=my_rank*local_num_step+1;
	const int right=left+local_num_step-1>num_steps?num_steps:left+local_num_step-1;
	double sum=0.;
	printf("线程ID=%d, 负责区间%d~%d; 传入参数step=%f\n",my_rank,left,right,step);
	for (int i=left;i<= right; i++){
		double x = ((double)i-0.5)*step;
		sum = sum + 4.0/(1.0+x*x);
	}
	return sum;
}


int main ()
{
	  int i;
	  double x, pi, sum = 0.0;
	  double start_time, run_time;

	  step = 1.0/(double) num_steps;

        	 
	  start_time = omp_get_wtime();

# 		pragma omp parallel num_threads(11) firstprivate(step)
		{
			const double partial_result=interval_sum_up(step, omp_get_num_threads());
			# pragma omp critical
			{pi+=step * partial_result;}
		}

	//   for (i=1;i<= num_steps; i++){
	// 	  x = (i-0.5)*step;
	// 	  sum = sum + 4.0/(1.0+x*x);
	//   }

	//   pi = step * sum;
	  run_time = omp_get_wtime() - start_time;
	  printf("\n pi with %ld steps is %lf in %lf seconds\n ",num_steps,pi,run_time);
}	  





